package cn.edu.hit.configcenter;

import cn.edu.hit.core.db.DBHelper;
//import cn.edu.hit.mongodb.Utils;
import cn.edu.hit.core.db.DataConnection;
import cn.edu.hit.core.db.DataConnectionLoader;
import cn.edu.hit.core.db.DataWriter;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
//import com.mongodb.client.MongoCollection;
//import com.mongodb.client.MongoDatabase;
import org.apache.commons.lang3.StringUtils;
import cn.edu.hit.core.Document;
//import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/rest/config")
public class ConfigureController {
    private DataConnection connection = DataConnectionLoader.getInstance();
    private DataWriter writer = (DataWriter) connection.getReader();
    private DBHelper dbHelper = new DBHelper(writer);
    final static Map<String, Boolean> isRunMap = Collections.singletonMap("isRun", true);

    @Autowired
    HttpServletRequest request;

    @CrossOrigin
    @RequestMapping(method = RequestMethod.GET, value = "/", produces = "application/json;charset=UTF-8")
    public Map<String, Boolean> isRun() {
        return isRunMap;
    }

    /**
     * TODO 约定 persistXXX 的路径 应与 XXX.type 一致,下同
     */
//    @POST
//    @Path("/{name}/{type}")
//    @Produces(MediaType.APPLICATION_JSON)
//    @Consumes({MediaType.APPLICATION_FORM_URLENCODED})
    @CrossOrigin
    @RequestMapping(method = RequestMethod.POST, value = "{name}/{type}", produces = "application/json;charset=UTF-8", consumes = "application/x-www-form-urlencoded")
    public List<Map> persist(
            @PathVariable("name") String name, @PathVariable("type") String type) throws IOException {
        String content = request.getParameter("content");
        name = StringUtils.trim(name);
        type = StringUtils.trim(type);
        List<Map> configure;
        TypeFactory typeFactory = TypeFactory.defaultInstance();
        JavaType mapType = typeFactory.constructRawMapType(Map.class);
        JavaType arrayMap = typeFactory.constructCollectionType(List.class, mapType);

        ObjectMapper mapper = new ObjectMapper();
        configure = mapper.readValue(content, arrayMap);

        if (configure == null) {
            return Collections.emptyList();
        }
        try {
            return dbHelper.persistConfigures(name, type, configure);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Collections.emptyList();
    }


    @CrossOrigin
    @RequestMapping(method = RequestMethod.POST, value = "component", produces = "application/json;charset=UTF-8", consumes = "application/x-www-form-urlencoded")
    public Map persistComponent() throws IOException {
        String content = request.getParameter("content");
        List<Map> configure;
        TypeFactory typeFactory = TypeFactory.defaultInstance();
        JavaType mapType = typeFactory.constructRawMapType(Map.class);
        JavaType arrayMap = typeFactory.constructCollectionType(List.class, mapType);

        ObjectMapper mapper = new ObjectMapper();
        configure = mapper.readValue(content, arrayMap);

        if (configure == null) {
            return Collections.emptyMap();
        }
        try {
            List<Map> persistResult = dbHelper.persistConfigures("global", "component", configure);
            if (persistResult != null && persistResult.size() > 0)
                return persistResult.get(0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Collections.emptyMap();
    }

    @CrossOrigin
    @RequestMapping(method = RequestMethod.DELETE, value = "{id}", produces = "application/json;charset=UTF-8")
    public Map<String, Boolean> remove(@PathVariable("id") String id) {
        id = StringUtils.trim(id);
        boolean isOk = dbHelper.removeConfigure(id);
        return Collections.singletonMap("isOK", isOk);
    }

    @CrossOrigin
    @RequestMapping(method = RequestMethod.GET, value = "load/{id}", produces = "application/json;charset=UTF-8")
    public Map<String, Object> loadById(@PathVariable("id") String id) {
        id = StringUtils.trim(id);
        Document document = dbHelper.getById(id);
        if (document == null) {
            return Collections.emptyMap();
        }
        document.put("_id", id);
        return document;
    }

//    @GET
//    @Path("/relation/{id}/{type}")
//    @Produces(MediaType.APPLICATION_JSON)
//    public List<String> loadConfigureRelations(@PathParam("id") String id,@PathParam("type") String type){
//        return dbHelper.loadConfigureRelations(id,type);
//    }

    static ObjectMapper mapper = new ObjectMapper();

    public static Document parse(String json) {
        try {
            return mapper.readValue(json, Document.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据模版查询
     */
    @CrossOrigin
    @RequestMapping(method = RequestMethod.POST, value = "query", produces = "application/json;charset=UTF-8", consumes = "application/x-www-form-urlencoded")
    public List<Map<String, Object>> loadByTemplate() throws IOException {
        String content = request.getParameter("content");
//        MongoDatabase database = Utils.getDatabase("fault");
//        MongoCollection<Document> configures = database.getCollection("configure",Document.class);
        /**
         * content 为查询模版，json格式
         */
//        String content = IOUtils.toString(request.getInputStream(),"utf8");
        Document document = parse(content);
//        if(document.containsKey("_id")){
//            String _id = document.getString("_id");
//            document.put("_id",new ObjectId(_id));
//        }
        return writer.queryByTemplate(document).stream()
                .map(d -> {
                    d.put("_id", d.getObjectId("_id"));
//                            return d.toJson(JSON_WRITER_SETTINGS);
                    return d;
                })
                .collect(Collectors.toList());
    }

    private Map<String, Object> singleValue(Object value) {
        return Collections.singletonMap("value", value);
    }

    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }
}
